﻿using System;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.WebPages.Html;
using Devotit.Umbraco.MvcBridge.Web;
using System.Web.WebPages;
using System.Web.Mvc.Html;
using System.Web.Helpers;

namespace Devotit.Umbraco.MvcBridge.Html
{
    public static class MvcBridgeExtensions
    {
        public static dynamic Node(this System.Web.Mvc.WebViewPage viewpage)
        {
            if (viewpage.ViewData.ContainsKey("UmbracoNode")) {
                return viewpage.ViewData["UmbracoNode"];
            }
            return default(dynamic);
        }

        public static dynamic Parameter(this System.Web.Mvc.WebViewPage viewpage)
        {
            if (viewpage.ViewData.ContainsKey("UmbracoParameter")) {
                return viewpage.ViewData["UmbracoParameter"];
            }
            return default(dynamic);
        }

        public static IHtmlString RenderMvcAction(this HtmlHelper helper, string action, string controller, string antiForgeryToken = "", dynamic node = null, dynamic parameter  = null)
        {
            var parentContext = HttpContext.Current.Request.RequestContext;
            if (parentContext != null) {
                using (var capture = new CaptureContext(parentContext.HttpContext)) {
                    var routedata = new RouteData(parentContext.RouteData.Route, parentContext.RouteData.RouteHandler);

                    if (routedata.Values.ContainsKey("controller")) {
                        routedata.Values.Add("controller", controller);
                    }
                    else {
                        routedata.Values["controller"] = controller;
                    }

                    if (routedata.Values.ContainsKey("action")) {
                        routedata.Values.Add("action", action);
                    }
                    else {
                        routedata.Values["action"] = action;
                    }

                    // check formtoken, if found we use POST else we use GET for our Request
                    string method = "GET";
                    if (parentContext.HttpContext.Request.HttpMethod == "POST" && parentContext.HttpContext.Request.Form.AllKeys.Contains("__RequestVerificationToken"))
                    {
                        try{
                            AntiForgery.Validate(parentContext.HttpContext, antiForgeryToken);
                            method = "POST";
                        }catch{
                        }

                    }

                    var httpContext = new OverrideRequestHttpContextWrapper(HttpContext.Current, method);
                    var context = new RequestContext(httpContext, routedata);
                    
                    var controllerfactory = System.Web.Mvc.ControllerBuilder.Current.GetControllerFactory();
                    var controllerInstance = controllerfactory.CreateController(context, controller) as System.Web.Mvc.ControllerBase;
                    
                    if (controllerInstance == null) {
                        throw new InvalidOperationException("controllerInstance is null");
                    }
                    
                    controllerInstance.ViewData["UmbracoNode"] = node;
                    controllerInstance.ViewData["UmbracoParameter"] = parameter;
                    
                    try {
                        ((System.Web.Mvc.IController)controllerInstance).Execute(context);
                    }
                    catch (Exception ex) {
                        capture.CaptureOutput.Write(ex.Message);
                    }
                    finally {
                        
                        controllerfactory.ReleaseController((System.Web.Mvc.IController)controllerInstance);
                    }
                    return helper.Raw(capture.GetOutput());
                }
            }
            else {
                return helper.Raw("");
            }
            
        }


    }

}